package org.jsoncrypto;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.json.JSONException;
import org.json.JSONObject;
import org.jsoncrypto.util.Base64;
import org.junit.Test;

public class JWEA128KWtest {

  @Test
  public void test() throws JcBaseException, JSONException {
    final String joeStr = "{\"iss\":\"joe\",\r\n" + " \"exp\":1300819380,\r\n"
        + " \"http://example.com/is_root\":true}";

    final String a128kw = "{\"alg\":\"A128KW\", \"enc\":\"A128GCM\", \"iv\":\"AxY8DCtDaGlsbGljb3RoZQ\"}";
    JSONObject header = new JSONObject(a128kw);
    JcLibEnc_AEAD enc = new JcEnc_A128GCM(header);
    JweA128KW jwe = new JweA128KW(enc);
    byte[] contentBytes = joeStr.getBytes();
    SecretKey key = new SecretKeySpec("password12345678".getBytes(), "AES");

    String encrypted = jwe.encrypt(contentBytes, key);
    String[] split = encrypted.split("\\.");
    assertEquals(4, split.length);
    
    JweA128KW x = new JweA128KW(encrypted);
    byte[] bytes = x.decrypt(key);
    assertEquals(joeStr, new String(bytes));
  }

  @Test
  public void testManipulatedHeader() {
    String encrypted = null;
    try {
      final String joeStr = "{\"iss\":\"joe\",\r\n" + " \"exp\":1300819380,\r\n"
          + " \"http://example.com/is_root\":true}";
  
      final String a128kw = "{\"alg\":\"A128KW\", \"enc\":\"A128GCM\", \"iv\":\"AxY8DCtDaGlsbGljb3RoZQ\"}";
      JSONObject header = new JSONObject(a128kw);
      JcLibEnc_AEAD enc = new JcEnc_A128GCM(header);
      JweA128KW jwe = new JweA128KW(enc);
      byte[] contentBytes = joeStr.getBytes();
      SecretKey key = new SecretKeySpec("password12345678".getBytes(), "AES");
  
      encrypted = jwe.encrypt(contentBytes, key);
      String[] split = encrypted.split("\\.");
      assertEquals(4, split.length);
      String jweHeaderStr = new String(Base64.decodeUrl(split[0]));
      JSONObject jweHeader = new JSONObject(jweHeaderStr);
      jweHeader.put("new", "bogus");
      jweHeaderStr = Base64.encodeBytes(
          jweHeader.toString().getBytes("utf-8"),
          org.jsoncrypto.util.Base64.DONT_BREAK_LINES
              | org.jsoncrypto.util.Base64.URL);
      encrypted = jweHeaderStr + "." + split[1] + "." + split[2] + "." + split[3];
      JweA128KW jweA128KW = new JweA128KW(encrypted);
      jweA128KW.decrypt(key);
      fail("should not be reached because the integrity check fails");
    } catch (Exception e) {
      Throwable t = e.getCause();
      if (!(t instanceof org.bouncycastle.crypto.InvalidCipherTextException)) {
        fail();
      }
    }
  }

}
